<template>
  <el-dialog
    v-model="permissiondialogFormVisible"
    :title="dialogTitle"
    :position="{ top: 40 }"
    width="600"
    :lock-scroll="false"
    class="permsimodal"
    @close="closeDialog"
  >
    <div class="tabs-permmison">
      <el-checkbox :model-value="getAllCheckState()" @change="handleCheckAllChange"
        >授予所有权限</el-checkbox
      >
      <el-divider />
      <el-tabs style="height: auto" tab-position="left" v-model:model-value="activeTab">
        <el-tab-pane
          v-for="item in tabs"
          :key="item.displayName"
          class="tab-pane"
          :label="getTreeCheckesWithLabel(item.displayName, item.permissions)"
          :name="item.name"
        >
          <div style="padding-left: 10px">
            <span style="font-size: 17px; font-weight: 800">{{ item.displayName }}</span>
            <el-divider />

            <el-checkbox
              :model-value="getItemCheckState(item.permissions, item)"
              @change="onCheckItemChange(item.permissions, $event, activeTab)"
              >全选</el-checkbox
            >

            <el-divider />
            <div class="permissionscroller">
              <el-scrollbar style="height: 100%">
                <el-tree
                  ref="treeRefList"
                  :custom-tree-id="item.name"
                  check-strictly
                  show-checkbox
                  default-expand-all
                  node-key="name"
                  :data="item.permissions"
                  :props="treeProps"
                  :default-checked-keys="item.defaultCheckedKeys"
                  @check="onTreeCheck"
                />
              </el-scrollbar>
            </div>
          </div>
        </el-tab-pane>
      </el-tabs>
    </div>
    <div class="modal-footer">
      <el-button type="primary" @click="editpermission">保存</el-button>
    </div>
  </el-dialog>
</template>
<script setup lang="ts">
import { getPermissions, updatePermissions } from "@/api/identity/permission/index";
import { PermissionQuery } from "@/api/permission/types";
import { getCurrentInstance } from "vue";
import type { ElTree } from "element-plus";

const {
  proxy: { $forceUpdate },
}: any = getCurrentInstance();

const Props = defineProps({
  FormVisible: { type: Boolean, default: true },
  Id: { type: String, default: null },
  title: { type: String, default: null },
  rolekey: { type: String, default: "" },
});
const emit = defineEmits(["closedialogevent", "refresh"]);

const defaultProps = {
  children: "child",
  label: "displayName",
  rolekey: "",
};
const permissiondialogFormVisible = ref<boolean>(false);
let permissiongroup = reactive<any>([]);
let permissionList = reactive<any>([]);

function handleCheckAllChange(val: any) {
  //console.log("groups", tabs, val, treeRefList.value);
  tabs.value.forEach((group) => {
    //console.log("groupitem", tabs, group);
    onCheckItemChange(group.permissions, val, group.name);
  });
}

function editpermission() {
  const checkList: any = [];
  // console.log(treeRefList.value);
  treeRefList.value?.forEach((treeRef) => {
    let checkData = treeRef.getCheckedKeys();
    if (checkData != null && checkData.length > 0) {
      checkData.map((checkItem) => {
        checkList.push(checkItem);
      });
    }
  });

  let providerName = "R";
  let providerKey = Props.rolekey;
  let newPerList: any = [];
  permissionList.forEach((perItem: any) => {
    if (checkList.includes(perItem.name)) {
      perItem.isGranted = true;
    } else {
      perItem.isGranted = false;
    }
    newPerList.push({
      name: perItem.name,
      isGranted: perItem.isGranted,
    });
  });
  let query: PermissionQuery = {
    providerName: providerName,
    providerKey: providerKey,
  };
  let payload: any = {
    permissions: newPerList,
  };
  console.log("payload", payload);
  updatePermissions(query, payload).then((res) => {
    ElNotification({
      title: "提示",
      message: "修改权限成功",
      type: "success",
      duration: 2000,
    });
    closeDialog();
    emit("refresh");
  });
}

function getCurrentTreeCheckes(tree: any[], checks: string[]) {
  tree.forEach((item: any) => {
    if (item.children) {
      getCurrentTreeCheckes(item.children, checks);
    }
    if (item.isGranted) {
      checks.push(item.name);
    }
  });
}

const treeProps = {
  children: "children",
  label: "displayName",
};
const tabs = ref<any[]>([]);
const activeTab = ref("");
async function getPermissionByRoleKeyV2(roleKey: string) {
  const list: any[] = [];
  const param: PermissionQuery = {
    providerName: "R",
    providerKey: roleKey,
  };
  const res = await getPermissions(param);
  //console.log("per", res);
  permissiongroup = res.groups;
  // 组装树
  permissiongroup.forEach((item: any) => {
    list.push({
      ...item,
      permissions: transformPermissionTree(item.permissions),
    });
  });

  // 设置默认选中
  list.forEach((item: any) => {
    const checks: string[] = [];
    getCurrentTreeCheckes(item.permissions, checks);
    item.defaultCheckedKeys = checks;
  });

  tabs.value = list;
  activeTab.value = list[0].name;
}

function getTreeCheckesWithLabel(displayName: string, permissions: any) {
  const checks: string[] = [];
  getCurrentTreeCheckes(permissions, checks);
  return `${displayName}(${checks.length})`;
}

function onTreeCheck(data: any, treeNode: any) {
  const setTreeCheck = (data: any) => {
    if (data.children && data.children.length) {
      data.children.forEach((item: any) => {
        setTreeCheck(item);
      });
    }

    if (treeNode.checkedKeys.length && treeNode.checkedKeys.includes(data.name)) {
      data.isGranted = true;
    } else {
      data.isGranted = false;
    }
  };
  setTreeCheck(data);
}

function getItemCheckState(permissions: any[], item: any) {
  const checks: string[] = [];

  let currentGroup = permissiongroup.find((group: any) => {
    return group.name === item.name;
  });

  //console.log('getItemCheckState',permissionList,permissions,item,permissiongroup,currentGroup)
  let nodes = currentGroup.permissions;
  getCurrentTreeCheckes(permissions, checks);
  return checks.length == nodes.length;
}

const treeRefList = ref<InstanceType<typeof ElTree>[]>();

function onCheckItemChange(permissions: any[], e: any, currentTab: any) {
  console.log("currentTab", currentTab, activeTab);
  const setTreeCheck = (data: any) => {
    if (data.children && data.children.length) {
      data.children.forEach((item: any) => {
        setTreeCheck(item);
      });
    }

    // check 属性改变，需要手动使用树方法更新
    const treeRef = treeRefList.value?.find(
      (treeComp) => treeComp.$attrs["custom-tree-id"] === currentTab
    );
    treeRef?.setChecked(data.name, e, true);
    // 更新数组选中状态，触发计数重新计算
    data.isGranted = e;
  };

  permissions.forEach((item: any) => {
    //console.log("setTreeCheck", item);

    setTreeCheck(item);
  });
}

async function createsetpermissiondialog(roleKey: string) {
  await getPermissionByRoleKeyV2(roleKey);
  permissiondialogFormVisible.value = true;
}

function closeDialog() {
  permissiondialogFormVisible.value = false;
  emit("closedialogevent", permissiondialogFormVisible.value);
}

const dialogTitle = computed(() => {
  return `权限:${Props.title}`;
});

function getAllCheckState() {
  //console.log("getAllCheckState", tabs);

  let nodes: any[] = [];
  //console.log("permissionList", permissionList);
  let checkNodes: any[] = [];
  treeRefList!.value?.forEach((treeRef) => {
    checkNodes.push(...treeRef.getCheckedNodes());
  });
  //console.log("checknodes", checkNodes);
  // console.log("allstatus", permissionList.length === checkNodes.length);
  return permissionList.length === checkNodes.length;
}
function transformPermissionTree(permissions: any, name: any = null) {
  const map = new Map<string, any>();
  if (!permissions || !permissions.some((v: any) => v.parentName === name)) {
    return Array.from(map.values());
  }
  const tmpperm = permissions.filter((x: any) => x.parentName == name);
  for (const i of tmpperm) {
    permissionList.push({
      ...i,
    }),
      map.set(i.name, {
        ...i,
        id: i.name,
        children: transformPermissionTree(permissions, i.name),
      });
  }

  return Array.from(map.values());
}

onMounted(() => {
  createsetpermissiondialog(Props.rolekey);
});
</script>
